<?php
/**
 *	[TWCMS] (C)2012 TongWang Inc.
 *	$Id: tpl.class.php 2 2013-04-27 07:14:17Z nanown@qq.com $
 */
defined('IN_TWCMS') || exit('Access Denied');

class tpl extends base{
	public $tpl_dir;			#主题目录
	public $php_dir;			#编译目录
	public $theme;				#主题文件夹名
	public $head_arr;			#头部代码
	public $del_php = true;		#清除PHP代码
	public $preg = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*';
	public $preg2 = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff\"\'\[\]\-\>\.]*';

	function __construct() {
		parent::load_db();
	}

	function display($tpl_name) {
		$this->head_arr = array();
		$tpl_file = $this->tpl_dir.str_replace(',', D, $tpl_name);
		$php_file = $this->php_dir.$this->theme.','.$tpl_name.'.php';

		if(!file_exists($tpl_file)) {
			loadErr('模板文件不存在： <b>'.$tpl_name.'</b>');
		}elseif(@filemtime($tpl_file) > @filemtime($php_file)) {
			$tpl_str = $this->tpl_parse(f_read($tpl_file));
			if(f_write($php_file, $tpl_str) === false) loadErr('模板文件写入失败： <b>'.str_replace(',','/',$tpl_name).'</b>');
		}
		include $php_file;		
	}

	function tpl_parse($str) {
		if($this->del_php) {
			$str=preg_replace('#\<\?.*?\?\>#s', '', $str);
			$str=preg_replace('#\<\?.*#s', '', $str);
		}
		$str=preg_replace('#\{tw\:('.$this->preg.')\040?([^\n\}]*?)\}(.*?){\/tw}#se', '$this->parse_mod(\'\\1\',\'\\2\',\'\\3\')', $str);

		$str=preg_replace('#\{loop\}(.*?)\{\/loop\}#se', '$this->parse_loop(\'$c->data\',\'\\1\')', $str);
		$str=preg_replace('#\{gloop\}(.*?)\{\/gloop\}#se', '$this->parse_loop(\'$global_c->data\',\'\\1\')', $str);
		while(preg_match('#\{loop\:\$?'.$this->preg2.'(?:\:'.$this->preg.')*\}.*?\{\/loop\}#s', $str))
			$str=preg_replace('#\{loop\:(\$?'.$this->preg2.'(?:\:'.$this->preg.')*)\}(.*?)\{\/loop\}#se', '$this->parse_loop(\'\\1\',\'\\2\')', $str);

		while(preg_match('#\{if\:[^\n\}]+\}.*?\{\/if\}#s', $str))
			$str=preg_replace('#\{if\:([^\n\}]+)\}(.*?)\{\/if\}#se', '$this->parse_if(\'\\1\',\'\\2\')', $str);

		$str=preg_replace('#\{\$(\S+)\$\}#', '<?php echo $\\1; ?>', $str);
		$str=preg_replace('#\{tw\.('.$this->preg.')\}#', '<?php echo $this->G[\'\\1\']; ?>', $str);
		$str=preg_replace('#\{v\.('.$this->preg.')\}#', '<?php echo $_ENV->V[\'\\1\']; ?>', $str);

		$str=preg_replace('#\{inc\:('.$this->preg.')\}#', '<?php $this->display(\'inc,\\1.htm\'); ?>',$str);
		$str='<?php defined(\'IN_TWCMS\') || exit(\'Access Denied\'); '.(empty($this->head_arr) ? '' : implode('',$this->head_arr)).' ?>'.$str;

		return str_replace('?><?php ', '', $str);
	}

	function parse_mod($class, $config, $str) {
		if(!file_exists(TWCMS_FRONT.$class.'.lib.php')) return '';

		$config = $this->rep_double($config);
		$str = $this->rep_double($str);
		preg_match_all('#('.$this->preg.')="(.*?)" #', $config.' ', $m);
		unset($m[0]);

		$setstr='';
		foreach($m[2] as $i=>$v) { if(!empty($v)) $setstr.="'".strtolower($m[1][$i])."'=>'".str_replace(array('\\',"'"), array('\\\\',"\'"), $v)."',"; }
		$setstr = '=new '.$class.'(array('.rtrim($setstr, ',').'));';

		if(substr($class, 0, 7) == 'global_') {
			$this->head_arr[$class] = '$global_c'.$setstr;
			while(preg_match('#\{gm\:'.$this->preg.'\}.*?{\/gm}#s', $str))
				$str = preg_replace('#\{gm\:('.$this->preg.')\}(.*?){\/gm}#s', '<?php if(method_exists($global_c,\'\\1\')){$global_c->\\1();?>\\2<?php } ?>', $str);
			$str = preg_replace('#\{gv\.('.$this->preg.')\}#', '<?php if(method_exists($global_c,\'\\1\')){echo $global_c->\\1();} ?>', $str);
			return $str;
		}
		$str=preg_replace('#\{tv\.('.$this->preg.')\}#', '<?php echo $_ENV->TV[\'\\1\']; ?>', $str);
		return '<?php $c'.$setstr.'?>'.$str.'<?php unset($c);$_ENV->TV=array(); ?>';
	}

	function parse_loop($preg, $str) {
		$Arr = array();
		foreach(explode(':', $this->rep_double($preg)) as $val) {
			if($val = trim($val)) $Arr[] = $val;
		}
		$Arr[0] = $this->rep_var($Arr[0]);
		$Arr[1] = empty($Arr[1]) ? 'lv' : $Arr[1];
		$Arr[2] = empty($Arr[2]) ? 'i' : $Arr[2];
		$str = preg_replace('#\{'.$Arr[1].'\.('.$this->preg.')\}#', '<?php echo $'.$Arr[1].'[\'\\1\']; ?>', $this->rep_double($str));
		$str = str_replace('{key:'.$Arr[2].'}', '<?php echo $'.$Arr[2].'; ?>', $str);
		return '<?php if(isset('.$Arr[0].') && is_array('.$Arr[0].')){foreach('.$Arr[0].' as $'.$Arr[2].'=>$'.$Arr[1].'){ ?>'.$str.'<?php }} ?>';
	}

	function parse_if($if, $str) {
		$str = preg_replace('#\{elseif\:([^\n\}]+)\}#','<?php }elseif (\\1) { ?>', $this->rep_double($str));
		$str = str_replace('{else}', '<?php }else{ ?>', $str);
		return '<?php if ('.$this->rep_var_if($this->rep_double($if)).') { ?>'.$str.'<?php } ?>';
	}

	function rep_var_if($str) {
		$str=preg_replace('#^v\.('.$this->preg.')$#','!empty($_ENV->V[\'\\1\'])', trim($str));
		$str=preg_replace('#^tw\.('.$this->preg.')$#','!empty($this->G[\'\\1\'])', $str);
		return $this->rep_var($str);
	}

	function rep_var($str) {
		$str=preg_replace('#v\.('.$this->preg.')#','$_ENV->V[\'\\1\']', $str);
		$str=preg_replace('#tw\.('.$this->preg.')#','$this->G[\'\\1\']', $str);
		return $str;
	}

	function rep_double($str) {
		return str_replace('\"', '"', $str);
	}
}